<template>
  <div class="container">
    <h1>实时车辆出场</h1>
    <div class="camera-container">
      <video ref="video" width="640" height="380" autoplay></video>
      <canvas ref="canvas" width="640" height="380"></canvas>
    </div>
    <div class="controls">
      <button @click="handleCapture">{{ isScanning ? '识别中...' : '实时识别车牌' }}</button>
      <input
        type="file"
        ref="fileInput"
        accept="image/*"
        style="display: none"
        @change="onFileSelected"
      >
    </div>
    <div class="result-container">
      <h2>识别结果</h2>
      <div v-html="result"></div>
    </div>
  </div>
</template>

<script>
import { vehicleExitParking, vehicleExitParking_ } from "@/api/Approach";

export default {
  name: "PlateRecognition",
  data() {
    return {
      stream: null,
      isScanning: false,
      scanInterval: null,
      result: "",
      imageResult: "",
    };
  },
  methods: {
    startCamera() {
      if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
        navigator.mediaDevices
          .getUserMedia({ video: true })
          .then((stream) => {
            this.stream = stream;
            this.$refs.video.srcObject = stream;
          })
          .catch((error) => {
            console.error("无法访问摄像头: ", error);
            this.result = "无法访问摄像头: " + error.message;
          });
      } else {
        this.result = "您的浏览器不支持摄像头访问";
      }
    },

    stopCamera() {
      if (this.stream) {
        this.stream.getTracks().forEach((track) => track.stop());
        this.$refs.video.srcObject = null;
        this.stream = null;
      }
    },

    startRealTimeRecognition() {
      if (this.isScanning) return;

      this.isScanning = true;
      this.result = "正在实时识别车牌...";

      this.scanInterval = setInterval(() => {
        const canvas = this.$refs.canvas;
        const video = this.$refs.video;
        canvas.getContext("2d").drawImage(video, 0, 0, canvas.width, canvas.height);
        const imageData = canvas.toDataURL("image/jpeg");
        this.recognizePlate(imageData, true);
      }, 500);
    },

    stopRealTimeRecognition() {
      this.isScanning = false;
      clearInterval(this.scanInterval);
    },

    recognizePlate(imageData, isRealTime = false) {
      const blob = this.dataURItoBlob(imageData);
      const formData = new FormData();
      formData.append("file", blob, "plate.jpg");

      fetch("http://127.0.0.1:5000/api/recognize", {
        method: "POST",
        body: formData,
      })
        .then((response) => response.json())
        .then((data) => {
          if (data.error) {
            if (!isRealTime) {
              this.result = "识别失败: " + data.error;
            }
          } else {
            if (isRealTime) {
              this.stopRealTimeRecognition();
              this.stopCamera();
            }

            this.result = `
              <p>车牌号码: <strong>${data.plate_number}</strong></p>
              <p>置信度: ${(data.confidence * 100).toFixed(2)}%</p>
            `;
            this.imageResult = `<img src="${data.image_url}" alt="识别结果">`;

            const ID = localStorage.getItem("userId");
            vehicleExitParking_({
              user_id: ID,
              license_plate_number: data["plate_number"],
            }).then((res) => {
              if (res.data.status == "error") {
                this.$message.error(res.data.message);
              } else if (res.data.status == "success") {
                this.$confirm(
                  `进厂时间:${res.data["entry_time"]}<br/>出场时间:${res.data["exit_time"]}<br/>当前余额:$${res.data["user_balance"]}<br/>产生费用:$${res.data["charge_amount"]}`,
                  "支付信息",
                  {
                    confirmButtonText: "确定支付",
                    cancelButtonText: "取消",
                    type: "success",
                    dangerouslyUseHTMLString: true,
                  }
                )
                  .then(() => {
                    vehicleExitParking({
                      user_id: ID,
                      license_plate_number: data["plate_number"],
                    })
                      .then((res) => {
                        console.log(res);
                        this.$message.success("出场成功");
                        const user = JSON.parse(localStorage.getItem("user"));
                        getRoleListApi({ name: user["name"] }).then((res) => {
                          if (res.data) {
                            localStorage.setItem("user", JSON.stringify(res.data[0]) || "");
                          }
                        });
                      })
                      .catch((err) => {
                        console.error("出场失败", err);
                        this.$message.error(err.response.data.message);
                      });
                  })
                  .catch(() => {
                    this.$message({
                      type: "info",
                      message: "取消出场",
                    });
                  });
              }
            });
          }
        })
        .catch((error) => {
          console.error("Error:", error);
          if (!isRealTime) {
            this.result = "识别过程中出错: " + error.message;
          }
        });
    },

    handleCapture() {
      if (!this.isScanning) {
        this.startCamera();
        setTimeout(() => {
          this.startRealTimeRecognition();
        }, 500);
      } else {
        this.stopRealTimeRecognition();
        this.stopCamera();
      }
    },

    handleUpload() {
      this.$refs.fileInput.click();
    },

    onFileSelected(e) {
      if (e.target.files && e.target.files[0]) {
        const reader = new FileReader();
        reader.onload = (event) => {
          this.recognizePlate(event.target.result);
        };
        reader.readAsDataURL(e.target.files[0]);
      }
    },

    dataURItoBlob(dataURI) {
      const byteString = atob(dataURI.split(",")[1]);
      const mimeString = dataURI.split(",")[0].split(":")[1].split(";")[0];
      const ab = new ArrayBuffer(byteString.length);
      const ia = new Uint8Array(ab);
      for (let i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
      }
      return new Blob([ab], { type: mimeString });
    },
  },
  beforeDestroy() {
    this.stopCamera();
    this.stopRealTimeRecognition();
  },
};
</script>

<style scoped>
.container {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
  text-align: center;
}

.camera-container {
  margin: 20px 0;
  position: relative;
}

.controls {
  margin: 20px 0;
}

button {
  margin: 0 10px;
  padding: 10px 20px;
}

.result-container {
  margin-top: 20px;
}

video,
canvas {
  max-width: 100%;
  height: auto;
}

canvas {
  display: none;
}
</style>
